import json

from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU

import base64
import pickle


# 购物车
class CartsView(View):

    # 加入购物车
    def post(self, request):

        json_data = json.loads(request.body)

        sku_id = json_data.get("sku_id")
        count = json_data.get("count")

        # 验证数据
        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "not fund sku"})

        try:
            count = int(count)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "not fund sku"})

        user = request.user
        # print(user.name)
        if user.is_authenticated:
            # 连接redis
            redis_cli = get_redis_connection("carts")

            # 操作hash
            redis_cli.hset("cart_%s" % user.id, sku_id, count)

            # 操作set
            redis_cli.sadd("selected_%s" % user.id, sku_id)

            return JsonResponse({"code": 0, "errmsg": 'ok'})
        else:
            # 未登陆

            cart_cookie = request.COOKIES.get("cart")

            if cart_cookie:
                carts = pickle.loads(base64.b64decode(cart_cookie))
            else:
                carts = {}

            if sku_id in carts:
                count += carts[sku_id]["count"]

            carts[sku_id] = {
                "count": count,
                "selected": True
            }

            # 数据转化 设置cookie

            carts_bytes = pickle.dumps(carts)

            b64carts = base64.b64encode(carts_bytes)

            response = JsonResponse({"code": 0, "errmsg": "ok"})

            response.set_cookie("cart", b64carts.decode(), max_age=3600 * 24 * 10)

            return response

    # 获取购物车数据
    def get(self, request):

        user = request.user

        # 判断是否登陆
        if user.is_authenticated:
            # 连接redis
            redis_cli = get_redis_connection("carts")
            # 获取 数据 hash
            skuid_count = redis_cli.hgetall("cart_%s" % user.id)
            # 获取 hset数据
            selected_skuids = redis_cli.smembers('selected_%s' % user.id)
            carts = {}
            # 把查询的数据 构造成cookie 里面的数据格式一样
            for sku_id, count in skuid_count.items():
                carts[int(sku_id)] = {
                    "count": int(count),
                    "selected": sku_id in selected_skuids
                }
        else:
            cart_cookie = request.COOKIES.get("cart")
            if cart_cookie:
                carts = pickle.loads(base64.b64decode(cart_cookie))
            else:
                carts = {}

        # 根据id查询信息 返回数据
        sku_ids = carts.keys()

        skus = SKU.objects.filter(id__in=sku_ids)

        sku_list = []
        for sku in skus:
            sku_list.append({
                "id": sku.id,
                "name": sku.name,
                "price": sku.price,
                "default_image_url": sku.default_image.url,
                "count": carts[sku.id]["count"],
                "selected": carts[sku.id]["selected"]
            })

        return JsonResponse({"code": 0, "errmsg": 'ok', "cart_skus": sku_list})

    # 修改购物车数据
    def put(self, request):
        json_data = json.loads(request.body)

        sku_id = json_data.get("sku_id")
        count = json_data.get("count")
        selected = json_data.get("selected")

        # 验证数据
        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "not fund sku"})

        try:
            count = int(count)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "not fund sku"})

        user = request.user
        if user.is_authenticated:

            # 修改redis数据

            # 获取redis的数据

            redis_cli = get_redis_connection("carts")
            # 重新设置 sku 数量
            redis_cli.hset("cart_%s" % user.id, sku_id, count)
            # set 无序无重复的集合
            # 设置sku 是否被选中
            if selected:
                redis_cli.sadd("selected_%s" % user.id, sku_id)
            else:
                redis_cli.srem("selected_%s" % user.id, sku_id)

            cart_sku = {"count": count, 'selected': selected, "sku_id": sku_id}

            # 返回响应
            return JsonResponse({"code": 0, "errmsg": "ok", "cart_sku": cart_sku})

        else:
            # 修改cookie数据
            cart_cookie = request.COOKIE.get("cart")

            carts = pickle.loads(base64.b64decode(cart_cookie))

            # 修改数量 和 是否选中
            carts[sku_id]["count"] = count

            carts[sku_id]["selected"] = selected

            # 编码返回数据
            carts_bytes = pickle.dumps(carts)

            b64carts = base64.b64encode(carts_bytes)

            cart_sku = {"count": count, "selected": selected, "sku_id": sku_id}

            response = JsonResponse({"code": 0, "errmsg": "ok", "cart_sku": cart_sku})

            response.set_cookie("cart", b64carts.decode(), max_age=3600 * 24 * 10)

            return response

    # 删除购物车数据
    def delete(self, request):
        json_data = json.loads(request.body)

        sku_id = json_data.get("sku_id")

        # 验证数据
        try:
            sku = SKU.objects.get(pk=sku_id)
        except Exception as e:
            print(e)
            return JsonResponse({"code": 400, "errmsg": "not fund sku"})

        user = request.user
        if user.is_authenticated:

            # 修改redis数据

            # 获取redis的数据

            redis_cli = get_redis_connection("carts")

            # hash
            redis_cli.hdel("cart_%s" % user.id, sku_id)

            # set
            redis_cli.srem("selected_%s" % user.id, sku_id)

            # 返回响应
            return JsonResponse({"code": 0, "errmsg": "ok"})

        else:
            # 修改cookie数据
            cart_cookie = request.COOKIE.get("cart")

            carts = pickle.loads(base64.b64decode(cart_cookie))

            del carts[sku_id]

            # 编码返回数据
            carts_bytes = pickle.dumps(carts)

            b64carts = base64.b64encode(carts_bytes)

            response = JsonResponse({"code": 0, "errmsg": "ok"})

            response.set_cookie("cart", b64carts.decode(), max_age=3600 * 24 * 10)

            return response


# 购物车全选
class CartsSelection(View):

    def put(self, request):
        json_data = json.loads(request.body)

        selected = json_data.get("selected")

        user = request.user
        if user.is_authenticated:

            # 修改redis数据

            # 获取redis的数据

            redis_cli = get_redis_connection("carts")
            # 获取 hash数据
            skuid_count = redis_cli.hgetall("cart_%s" % user.id)
            # 获取所有的key
            sku_ids = skuid_count.keys()

            pl = redis_cli.pipeline()
            # 开启事务

            # 因为 set是自动去重的
            if selected:
                pl.sadd("selected_%s" % user.id, *sku_ids)
            else:
                pl.srem("selected_%s" % user.id, *sku_ids)
            pl.execute()

            # 返回响应
            return JsonResponse({"code": 0, "errmsg": "ok"})

        else:
            # 修改cookie数据
            cart_cookie = request.COOKIE.get("cart")

            carts = pickle.loads(base64.b64decode(cart_cookie))

            # 修改数量 和 是否选中

            for sku_id in carts.keys():
                carts[sku_id]["selected"] = selected

            # 编码返回数据
            carts_bytes = pickle.dumps(carts)

            b64carts = base64.b64encode(carts_bytes)

            response = JsonResponse({"code": 0, "errmsg": "ok"})

            response.set_cookie("cart", b64carts.decode(), max_age=3600 * 24 * 10)

            return response


# 首页预览购物车
class CartsSimple(View):

    def get(self, request):
        # 判断用户是否登陆
        user = request.user

        # 判断是否登陆
        if user.is_authenticated:
            # 连接redis
            redis_cli = get_redis_connection("carts")
            # 获取 数据 hash
            skuid_count = redis_cli.hgetall("cart_%s" % user.id)
            # 获取 hset数据
            selected_skuids = redis_cli.smembers('selected_%s' % user.id)
            carts = {}
            # 把查询的数据 构造成cookie 里面的数据格式一样
            for sku_id, count in skuid_count.items():
                carts[int(sku_id)] = {
                    "count": int(count),
                    "selected": sku_id in selected_skuids
                }
        else:
            cart_cookie = request.COOKIES.get("cart")
            if cart_cookie:
                carts = pickle.loads(base64.b64decode(cart_cookie))
            else:
                carts = {}

        # 根据id查询信息 返回数据
        sku_ids = carts.keys()

        skus = SKU.objects.filter(id__in=sku_ids)

        sku_list = []
        for sku in skus:
            sku_list.append({
                "id": sku.id,
                "name": sku.name,
                "price": sku.price,
                "default_image_url": sku.default_image.url,
                "count": carts[sku.id]["count"],
                "selected": carts[sku.id]["selected"]
            })

        return JsonResponse({"code": 0, "errmsg": 'ok', "cart_skus": sku_list})
